package com.qinglei.recoup.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

@Slf4j
public class JsonUtils {
    private static final ObjectMapper MAPPER = new ObjectMapper();

    public static JsonNode stringToJson(String content) {
        try {
            JsonNode jsonNode = MAPPER.readTree(content);
            return jsonNode;
        } catch (IOException e) {
            log.error("objectToJson error:", e);
        }
        return null;
    }

    public static int[] readIntArray(JsonNode node) {
        int size = node.size();
        int[] arr = new int[size];
        Iterator<JsonNode> iterator = node.iterator();
        int idx = 0;
        while (iterator.hasNext()) {
            JsonNode item = iterator.next();
            arr[idx++] = item.asInt();
        }
        return arr;
    }

    public static long[] readLongArray(JsonNode node) {
        int size = node.size();
        long[] arr = new long[size];
        Iterator<JsonNode> iterator = node.iterator();
        int idx = 0;
        while (iterator.hasNext()) {
            JsonNode item = iterator.next();
            arr[idx++] = item.asLong();
        }
        return arr;
    }

    public static String objectToJson(Object data) {
        try {
            String result = MAPPER.writeValueAsString(data);
            return result;
        } catch (JsonProcessingException e) {
            log.error("objectToJson error:", e);
        }
        return null;
    }

    public static <T> T jsonToBean(String jsonData, Class<T> beanType) {
        try {
            T result = MAPPER.readValue(jsonData, beanType);
            return result;
        } catch (Exception e) {
            log.error("jsonToBean error:", e);
        }

        return null;
    }

    /**
     * 字符串转Java对象（自动将下换线转换为驼峰）
     * @param jsonData
     * @param beanType
     * @param <T>
     * @return
     */
    public static <T> T jsonToBeanExt(String jsonData, Class<T> beanType) {
        PropertyNamingStrategy propertyNamingStrategy = MAPPER.getPropertyNamingStrategy();
        try {
            MAPPER.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
            T result = MAPPER.readValue(jsonData, beanType);
            return result;
        } catch (Exception e) {
            log.error("jsonToBean error:", e);
        } finally {
            MAPPER.setPropertyNamingStrategy(propertyNamingStrategy);
        }
        return null;
    }

    public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);

        try {
            List<T> resultList = MAPPER.readValue(jsonData, javaType);
            return resultList;
        } catch (Exception e) {
            log.error("jsonToList error:", e);
        }

        return null;
    }

    public static <K, V> Map<K, V> jsonToMap(String jsonData, Class<K> keyType, Class<V> valueType) {
        JavaType javaType = MAPPER.getTypeFactory().constructMapType(Map.class, keyType, valueType);

        try {
            Map<K, V> resultMap = MAPPER.readValue(jsonData, javaType);
            return resultMap;
        } catch (Exception e) {
            log.error("jsonToMap error:", e);
        }

        return null;
    }

    public static Double[] readDoubleArray(JsonNode node) {
        int size = node.size();
        Double[] arr = new Double[size];
        Iterator<JsonNode> iterator = node.iterator();
        int idx = 0;
        while (iterator.hasNext()) {
            JsonNode item = iterator.next();
            arr[idx++] = Double.parseDouble(String.format("%.6f", item.asDouble())) ;
        }
        return arr;
    }

    public static ObjectMapper getMAPPER() {
        return MAPPER;
    }

    public static void main(String[] args) {
        double ss =-0.031584665179252625;
        System.out.println();
        String objectStr="{\"name\":\"JSON\",\"age\":\"24\",\"address\":\"北京市西城区\"}";
        Object o = jsonToBean(objectStr, Object.class);
        System.out.println("o instanceof Map: " + (o instanceof Map));
        HashMap<String, Object> map = (HashMap<String, Object>) o;
        System.out.println("map: " + map);
        String content = "{\"gmtCreate\": 1646472916830,\"items\": {\"V4:TCFg\": {\"value\": 0,\"time\": 1645522395437},\"V4:BMPR2\": {\"value\": [0.038009293377399445, 0.048600275069475174, 0.044545210897922516, 0.07883597165346146, 0.10980719327926636, 0.1147836297750473, 0.12415896356105804, 0.1025770828127861, 0.08425576239824295, 0.0699511393904686],\"time\": 1645522395437},\"V4:TRaILFg\": {\"value\": 0,\"time\": 1645522395437},\"V4:HRBpRe\": {\"value\": 59,\"time\": 1645522395437},\"V4:BPh\": {\"value\": [-53.657772064208984, -53.729042053222656, -53.68932342529297, -53.67306900024414, -53.686439514160156, -53.64813995361328, -53.680686950683594, -53.66789627075195, -53.712860107421875, -53.666255950927734],\"time\": 1645522395437},\"V4:proCode\": {\"value\": 2,\"time\": 1645522395437},\"V4:BREBP\": {\"value\": 23,\"time\": 1645522395437},\"V4:TSFg\": {\"value\": 1,\"time\": 1645522395437},\"V4:frameNo\": {\"value\": 24575,\"time\": 1645522395437},\"V4:MNoP\": {\"value\": 27.569732666015625,\"time\": 1645522395437},\"V4:LTRaB\": {\"value\": 42,\"time\": 1645522395437},\"V4:BDEF\": {\"value\": 1.0349833965301514,\"time\": 1645522395437},\"V4:OBAcFg\": {\"value\": 0,\"time\": 1645522395437},\"V4:SFg\": {\"value\": 0,\"time\": 1645522395437},\"V4:HBa2\": {\"value\": 0,\"time\": 1645522395437},\"V4:MH\": {\"value\": [27.896963119506836, 32.374629974365234, 31.092153549194336, 29.817401885986328, 32.53023910522461, 33.41520690917969, 33.5565071105957, 32.935794830322266, 32.746036529541016, 29.745351791381836, 28.4896297454834, 33.628719329833984, 34.80115509033203, 32.14596176147461, 27.39165687561035, 25.563434600830078, 27.953536987304688, 27.393823623657227, 25.950908660888672, 25.468721389770508, 25.923986434936523, 27.31072998046875, 27.55643653869629, 27.48445701599121, 28.382226943969727, 28.664905548095703, 25.706886291503906, 25.045021057128906, 24.698740005493164, 24.972875595092773, 24.979698181152344, 24.515552520751953, 24.632572174072266, 24.04346466064453, 24.027082443237305, 24.073331832885742, 23.664716720581055, 25.85471534729004, 24.036636352539062, 24.23166847229004, 31.662395477294922, 38.38345718383789, 43.92253112792969, 48.09929656982422, 46.317718505859375, 52.65145492553711, 53.82261657714844, 46.00929641723633, 41.08580780029297, 38.64052963256836, 35.333316802978516, 35.23950958251953, 42.006717681884766, 41.81867218017578, 36.01763153076172, 41.55790710449219, 44.98640441894531, 44.15850067138672, 42.859596252441406, 40.54097366333008, 37.63185119628906, 36.53168487548828, 35.08510208129883, 35.42538833618164],\"time\": 1645522395437},\"V4:BPhERaB\": {\"value\": 23,\"time\": 1645522395437},\"V4:HHm2\": {\"value\": -9.221837043762207,\"time\": 1645522395437},\"V4:HPhERB\": {\"value\": 23,\"time\": 1645522395437},\"V4:THRBpEBAg\": {\"value\": 0,\"time\": 1645522395437},\"V4:CABS\": {\"value\": [64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 2201.4423828125, 1961.0460205078125, 2166.525634765625, 2010.2047119140625, 1825.6922607421875, 2145.947509765625, 1966.4163818359375, 2019.035400390625, 2239.244140625, 1671.7513427734375, 6040.19287109375, 6890.12060546875, 5785.83203125, 5659.0986328125, 6477.56103515625, 5405.25537109375, 6044.685546875, 6590.68017578125, 6025.20556640625, 6520.9140625, -1229.1484375, -1440.8408203125, -1119.5732421875, -1475.5712890625, -1437.88330078125, -1366.64501953125, -1283.1251220703125, -1253.9881591796875, -1042.843994140625, -1383.34521484375, -155.92495727539062, -125.93577575683594, -155.71896362304688, -155.9204864501953, -82.0123291015625, -164.2904052734375, -119.66346740722656, -170.684814453125, -191.90545654296875, -162.97467041015625, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\"time\": 1645522395437},\"V4:HS\": {\"value\": [0.004358003847301006, 0.01391375157982111, 0.014872596599161625, 0.0055069997906684875, -0.002816232619807124, -0.003650276456028223, -0.004235600121319294, -0.010846245102584362, -0.01825542375445366, -0.016706978902220726],\"time\": 1645522395437},\"V4:OBFg2\": {\"value\": 0,\"time\": 1645522395437},\"V4:BS\": {\"value\": [-0.02338925376534462, -0.02461903542280197, -0.024007506668567657, -0.02252621203660965, -0.01495105866342783, -0.0016162502579391003, 0.010181782767176628, 0.01457265019416809, 0.008072856813669205, -0.004473297391086817],\"time\": 1645522395437},\"V4:OBFg\": {\"value\": 0,\"time\": 1645522395437},\"V4:OBFg1\": {\"value\": 0,\"time\": 1645522395437},\"V4:BMReFg\": {\"value\": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\"time\": 1645522395437},\"V4:HPh\": {\"value\": [-91.35688781738281, -91.42816162109375, -91.38844299316406, -91.3721923828125, -91.38555908203125, -91.34725952148438, -91.37980651855469, -91.36701965332031, -91.41197967529297, -91.36537170410156],\"time\": 1645522395437},\"V4:AAFg\": {\"value\": 0,\"time\": 1645522395437},\"V4:protocol\": {\"value\": 2,\"time\": 1645522395437},\"V4:HRBpHmAg\": {\"value\": 0,\"time\": 1645522395437}}}";
        JsonNode rootNode = stringToJson(content);
        JsonNode itemsNode = rootNode.get("items");
        System.out.println(itemsNode);
        ObjectNode objectNode = MAPPER.createObjectNode();
        objectNode.put("SN", "12345678");
        Instant instant = Instant.ofEpochMilli(rootNode.get("gmtCreate").asLong());
        LocalDateTime time = LocalDateTime.ofInstant(instant, ZoneOffset.of("+8"));
        objectNode.put("TIME", DateUtil.formatFullTime(time, DateUtil.FULL_TIME_MILLI_BAR_PATTERN));
        Iterator<Map.Entry<String, JsonNode>> iterator = itemsNode.fields();
        while (iterator.hasNext())
        {
            Map.Entry<String, JsonNode> entry = iterator.next();
            // System.out.println(entry.getKey() + ":" + entry.getValue());
            // System.out.println(entry.getKey() + ":" + entry.getValue().get("value"));
            objectNode.set(entry.getKey().split(":")[1], entry.getValue().get("value"));
        }
        Object object = jsonToBean(objectNode.toString(), Object.class);
        System.out.println(object);
        HashMap<String, Object> objectMap = (HashMap<String, Object>) object;
        System.out.println("objectMap: " + objectMap);
        System.out.println("SN: " + objectMap.get("SN"));
        Date date = new Date();
        System.out.println(date.getTime());
    }
}
